using System.Collections.Generic;

namespace IQIGame.Onigao.GamePlay
{
    /// <summary>
    /// 用于系统模块内部核心控制器的基类
    /// 系统模块：关卡，战斗等
    /// 核心控制器：相机控制器，场景控制器，实体控制器等
    /// </summary>
    public abstract class TController : TObject
    {
        public TController parent { get; private set; }
        protected List<TController> _subCtrls;

        public T AddSubController<T>() where T : TController, new()
        {
            T t = new T();
            AddSubController(t);
            return t;
        }

        public void AddSubController(TController controller)
        {
            controller.parent = this;
            _subCtrls = _subCtrls ?? new List<TController>();
            _subCtrls.Add(controller);
        }

        public void RemoveSubController(TController controller)
        {
            _subCtrls?.Remove(controller);
            controller.Dispose();
        }

        public void Update(float deltaTime)
        {
            OnUpdate(deltaTime);
            if (_subCtrls != null)
            {
                foreach (var ctrl in _subCtrls)
                {
                    ctrl.Update(deltaTime);
                }
            }
        }

        public void LateUpdate()
        {
            OnLateUpdate();
            if (_subCtrls != null)
            {
                foreach (var ctrl in _subCtrls)
                {
                    ctrl.LateUpdate();
                }
            }
        }

        public void DispatchInnerEvent(TControllerEvent evt)
        {
            OnControllerEvent(evt);
            if (_subCtrls != null)
            {
                foreach (var ctrl in _subCtrls)
                {
                    ctrl.DispatchInnerEvent(evt);
                }
            }
        }

        protected virtual void OnControllerEvent(TControllerEvent evt)
        {

        }

        protected virtual void OnUpdate(float deltaTime)
        {

        }

        protected virtual void OnLateUpdate()
        {

        }

        public override void Dispose()
        {
            base.Dispose();

            if (_subCtrls != null)
            {
                foreach (var ctrl in _subCtrls)
                {
                    ctrl.Dispose();
                }
                _subCtrls = null;
            }
        }
    }
}
